import com.troyworks.framework.ui.BaseComponent;
import com.troyworks.framework.loader.MCLoader;
import de.alex_uhlmann.animationpackage.animation.Alpha;
import com.robertpenner.easing.Elastic;
import com.troyworks.framework.ui.IHaveChildrenComponents;
import com.troyworks.hsmf.AEvent;
import com.troyworks.util.DesignByContract;
import com.troyworks.mediaplayer.MixinPlayer;
import com.troyworks.framework.ui.DragProxy;
import com.troyworks.events.EVTD;
import com.troyworks.events.TEventDispatcher;
import com.troyworks.framework.ui.layout.Bounds2;
/**
 * This player is a generic player for flash content that typically 
 *  a cover (eg. for a loading animation
 *  a background (e.g. a flat color)
 *  
 *  it can accept, flv,swf, images or attachMovies from the library
 *  it also scales and centers appropriately.
 *  
 * @author Troy Gardner
 */
class com.troyworks.mediaplayer.ui.MultiMediaWindow extends BaseComponent {
	public var base_mc : MovieClip;
	public static var _className : String = "com.troyworks.mediaplayer.ui.MultiMediaWindow";
	//These exist in a heirarchy of
	// MyArt ( a clip you create and pass in)
	//  |_Mask _vectormask_mc (a mask over the content)
	//  |_Shell
	//      |_frame_mc (a picture frame concept for loading etc.
	//      |_cover_mc (a cover for loading etc.
	//      |_overlay_mc (place to put textfields) (NOT IMPLMENTED)
	//      |_bitmap_mc   (bitmap effects_of the main content
	//      |_ph_mc (PlaceHolder holds the main content, SWF, JPG etc)
	//      |_video (an optional container for FLV player)
	//      |_background_mc
	public var x : Number = 0;
	public var y : Number = 0;
	public var width : Number = 0;
	public var height : Number = 0;
	public var autoStart : Boolean = true;
	public var autoRewind : Boolean = true;
	public var activateMXP : Boolean = false;
	
	public var hasOnLoad : Boolean = false;
	/* A controller for loaded swfs */
	public var mxP : MixinPlayer;
	/////////////////////////////////////
	private var contentPATH : Object = null;
	private var maskPATH : Object = null;

	private var framePATH : Object;

	private var coverPATH : Object;

	private var loadingProgressPATH : Object;

	private var backgroundPATH : Object;

	private var contentFilters : Array;

	private var mcL : MCLoader;
	public var isDraggable:Boolean = false;
	public static var EVTD_RECIEVED_CONTENT:String = "EVTD_RECIEVED_CONTENT";
	/******************************************
	 * Constructor
	 */
	public function MultiMediaWindow(placeHolderArea_mc : MovieClip) {
		super();
		trace("cccccccccccccccccccccccccccccccccccccccccccccc");
		trace("cccccccccccccccccccccccccccccccccccccccccccccc");
		trace("ccccccccccccccccccccccc MultiMediaWindow ccccccccccccccccccccccc");
		trace("ccccccccccccccccccc placeHolderArea_m:  " + placeHolderArea_mc + " cccccccccccccccccccccccccccc");
		trace("ccccccccccccccccccc this:  " + this + " ccccccccccccccccccccccccccc");
		trace("cccccccccccccccccccccccccccccccccccccccccccccc");
		base_mc = (placeHolderArea_mc == null)?this:placeHolderArea_mc;
		if(maskPATH != null){
			setMaskTo(maskPATH);
		}
		if(framePATH != null){
			setFrameTo(framePATH);
		}
		if(coverPATH != null){
			setCoverTo(coverPATH);
		}
		
		if(contentPATH != null){
			setContentTo(contentPATH);
		}
		if(backgroundPATH != null){
			setBackgroundTo(backgroundPATH);
		}
		
	}
	function onPressHandler() :Void{
		trace("on dragProxyRequest");

	
	
	    DragProxy.getInstance().setDragSource(this);
		onMouseUp = releaseDragProxy;
	}
	function releaseDragProxy():Void{
		DragProxy.getInstance().releaseDragSource(this);
		delete(onMouseUp);
	}
	public static function createLoadingShell(_mc : MovieClip) : MovieClip{

		var shell_mc : MovieClip = _mc.createEmptyMovieClip("shell_mc", 2);//_mc.getNextHighestDepth());
		_mc.createEmptyMovieClip("mask_mc",3);// _mc.getNextHighestDepth());
		//shell_mc._visible = false;
		///////// Create the placeholder and the cover for it.
		var background_mc : MovieClip = shell_mc.createEmptyMovieClip("background_mc", 2);
		var ph_mc : MovieClip = shell_mc.createEmptyMovieClip("ph_mc", 3);
		
		shell_mc.createEmptyMovieClip("bitmap_mc", 4);
		shell_mc.createEmptyMovieClip("cover_mc", 5);
		shell_mc.createEmptyMovieClip("loadingProgress_mc", 6);
		shell_mc.createEmptyMovieClip("frame_mc", 7);
		return ph_mc;
	}
	public static function setClipContentTo(base_mc : Object, target_mc : MovieClip, o : Object, alpha : Number, loadingProgress_mc : MovieClip) : MCLoader{
		trace("setClipContentTo : " + o);
		DesignByContract.REQUIRE(target_mc != null,"seClipContentTo target cannot be null");
		///////////////// Validate data//////////////////
		alpha = (alpha == null)?100:alpha;
		var bounds : Object = new Object();
		 if(base_mc instanceof MultiMediaWindow){
			trace("----using MultiMediaWindow");
			var mmW : MultiMediaWindow = MultiMediaWindow(base_mc);
			bounds.x = 0;
			bounds.y = 0;
			bounds.width = mmW.base_mc._oawidth;//width-2;
			bounds.height = mmW.base_mc._oaheight;//mxP.height-2;
		}else if(base_mc instanceof MovieClip){
			trace("----using MoveClip");
			bounds.x = 0;
			bounds.y = 0;
			bounds.width = base_mc._oawidth;//base_mc._width;
			bounds.height = base_mc._oaheight;//
		}
//		trace(util.Trace.me(bounds, "SETTING CLIP CONTENT ", true));
//		trace(util.Trace.me(base_mc, "LOOKING FOR LOADING ", true));
		//////////Process the request/////////////
		
		if(o== null){
			trace("HIGHLIGHTB  removing");
			//rmove the clip
			target_mc.clear();
			target_mc.removeMovieClip();
			target_mc.unloadMovie();
		}else if(typeof(o) == "string"){
			var s : String = String(o);
			var mcL : MCLoader = new MCLoader(s,target_mc);

			if(mcL.isJPEG || mcL.isPNG || mcL.isGIF){
				//load an IMAGE
				trace("HIGHLIGHTB  loading an Image");
				mcL.smooth = true;
				mcL.loadingProgress_mc = (loadingProgress_mc.LoadingProgress_mc== null)?loadingProgress_mc:loadingProgress_mc.LoadingProgress_mc;
				mcL.startLoading();
			}else if(mcL.isSWF){
				//load a SWF
				trace("HIGHLIGHTB loading a SWF");
				mcL.useContainer = true;
				mcL.loadingProgress_mc = (loadingProgress_mc.LoadingProgress_mc== null)?loadingProgress_mc:loadingProgress_mc.LoadingProgress_mc;
				mcL.startLoading();
			}else{
				///attach a movie
				trace("HIGHLIGHTB attempting to attach Movie: " + String(o) + " target " + target_mc);
				target_mc.attachMovie(String(o),String(o)+"_mc",3);
				mcL = null;
			}
			return mcL;
		}else if(typeof(o) == "number"){
			trace("---------CREATING A VECTOR BACKGOUND --------w: " + bounds.width + " h: " + bounds.height + " " + Number(o)+ " alpha "  + alpha);
			///create a vector colored  background
			target_mc.moveTo(0, 0);
			target_mc.beginFill(Number(o), alpha);
			target_mc.lineTo(bounds.width, 0);
			target_mc.lineTo(bounds.width, bounds.height);
			target_mc.lineTo(0, bounds.height);
			target_mc.endFill();
		}else{
			DesignByContract.REQUIRE(false, "MultiMediaWindow passed an invalid type" + o);
		}
		return null;
	}
	////////////////////////////////////////////////////////////////////////////////////////
	public function setMaskTo(o : Object) : Void{

		maskPATH = (o == null)?0xFF0000:o;
		if(hasOnLoad){
			trace(_name+".setMaskTo xxxxxxxxxxxxxxxxxxxxxxxxxx" + o);
			setClipContentTo(this, base_mc.mask_mc, maskPATH);
			//trace("attempting to set mask" + base_mc.shell_mc + " " + base_mc.mask_mc);
			base_mc.shell_mc.setMask(base_mc.mask_mc);
		}
			
	}
	public function setFrameTo(o : Object, alpha : Number) : Void{
		trace(_name+".setFrameTo " + o + " alpha : " + alpha);
		framePATH = o;
		if(hasOnLoad){
			setClipContentTo(this, base_mc.shell_mc.frame_mc, framePATH, alpha);
		}
	}
	public function setLoadingProgressIndicatorTo(o : Object, alpha : Number) : Void{
		trace(_name+".setLoadingProgressIndicatorTo " + o + " alpha : " + alpha);
		loadingProgressPATH = o;
		if(hasOnLoad){
			setClipContentTo(this, base_mc.shell_mc.loadingProgress_mc, loadingProgressPATH, alpha);
		}
		
	}
	public function setCoverTo(o : Object, alpha : Number) : Void{
		trace(_name+".setCoverTo " + o + " alpha : " + alpha);
		coverPATH = o;
		if(hasOnLoad){
			REQUIRE(base_mc.shell_mc.cover_mc != null, " setCoverTo base_mc.shell_mc.cover_mc cannot be null");
			setClipContentTo(this, base_mc.shell_mc.cover_mc, coverPATH, alpha, base_mc.shell_mc.loadingProgress_mc);
		}
	}
	public function setContentTo(o : Object, alpha : Number, filters : Array, isInteractive:Boolean) : Void{
		trace(_name+".setContentTo " + o+ " alpha : " + alpha + " filters " + filters +  " isInteractive " + isInteractive + " hasOnLoad: " + hasOnLoad);
		contentPATH = o;
		contentFilters = filters; 
		if(hasOnLoad){
		
			setCoverTo(0xffffff, 100);
			
			//unload whatever was in the spot before

			base_mc.shell_mc.createEmptyMovieClip("ph_mc", 3);
		//	base_mc._width = base_mc._owidth;
		//	base_mc._height = base_mc._oheight;
			//snapshotDimensions(base_mc);
			REQUIRE(base_mc.shell_mc.ph_mc != null, " setContentTo base_mc.shell_mc.ph_mc cannot be null");
	
		//	base_mc.shell_mc.ph_mc._visible = false;
			trace(util.Trace.me(base_mc, "MultiMediaWindow check", true));
			 mcL = setClipContentTo(this,base_mc.shell_mc.ph_mc, contentPATH, alpha, base_mc.shell_mc.loadingProgress_mc.LoadingProgressIndicator_mc);
			if(mcL != null){
				if(mcL.isSWF && (isInteractive == null || isInteractive == false) && (contentPATH.indexOf("KTLoader.swf")==-1)){
					mxP = new MixinPlayer(mcL.actTarget);
					mxP.autoStart = autoStart;
					mxP.autoRewind = autoRewind;
					if(activateMXP){
						mxP.init();
					}
				}else{
					mxP = null;
				}
	
				mcL.addEventListener(MCLoader.EVT_DATA_LOADED, this, this.onRecievedContentData);	
				mcL.addEventListener(MCLoader.EVT_FINISHED_LOADING, this, this.onSetContent);
			}else{
				onRecievedContentData();
				onSetContent();
			}
		}
	}
	public function setBackgroundTo(o : Object, alpha : Number) : Void{
		trace(this._name + " setBackgroundTo " + o+ " alpha : " + alpha);
		backgroundPATH = o;
		if(hasOnLoad){
			REQUIRE(base_mc.shell_mc.background_mc != null, " setContentTo base_mc.shell_mc.background_mc cannot be null");
			setClipContentTo(this,base_mc.shell_mc.background_mc, o, alpha, base_mc.shell_mc.loadingProgress_mc);
		}
	}
	public function onRecievedContentData() : Void{
		trace("#######################################################");
		trace("####################### onRecievedContentData ################################");
		trace("################## content xscale " +base_mc.shell_mc.ph_mc._xscale + " " + base_mc.shell_mc.ph_mc._yscale + " ################");
		trace("############### content actual " + 	base_mc.shell_mc.ph_mc._width +", "+ 	base_mc.shell_mc.ph_mc._height +  " ################ orig display " + base_mc._owidth + " " + base_mc._oheight  + " ########################");
		trace("################# content viewport? " + mcL.actTarget.viewport_mc._width + " "  + mcL.actTarget.viewport_mc._height+ " ######################################");
		
		if(mcL.actTarget.viewport_mc == null){
			trace("no view port ");
			snapshotDimensions(base_mc.shell_mc.ph_mc);
			trace(util.Trace.me(base_mc.shell_mc.ph_mc, "base_mc.shell_mc.ph_m"));
			scaleTo(null, base_mc.shell_mc.ph_mc, base_mc._oawidth, base_mc._oaheight);
		}else{
			trace("using viewport");
//			snapshotDimensions(base_mc.shell_mc.ph_mc);
//			scaleTo(null, base_mc.shell_mc.ph_mc, base_mc._oawidth, base_mc._oaheight);
			snapshotDimensions(mcL.actTarget );
			scaleTo(null, mcL.actTarget , base_mc._oawidth, base_mc._oaheight, mcL.actTarget.viewport_mc._width, mcL.actTarget.viewport_mc._height);

		//	var b:Object = new Object();
		//	b._width = base_mc._owidth;
		//	b._height = base_mc._oheight;
		//	scaleTo2( base_mc.shell_mc.ph_mc, b);
		}
		trace("applying filters " + contentFilters);
		if(contentFilters !=null){

			base_mc.shell_mc.ph_mc.filters = contentFilters;
		}
		base_mc.shell_mc.ph_mc._visible = true;
//		base_mc.shell_mc.ph_mc._width = width;//base_mc._owidth;
//		base_mc.shell_mc.ph_mc._height =height;// base_mc._oheight;
		trace("ERROR dispatchnig EVTD_RECIEVED_CONTENT");
		var evtd:EVTD = new EVTD(EVTD_RECIEVED_CONTENT, this);
		dispatchEvent(evtd);
	}
	public function getContentBounds(context:MovieClip):Bounds2{
		if(context == null){
			context = base_mc.shell_mc;
		}
		var b2:Bounds2 = new Bounds2(base_mc.shell_mc.ph_mc.getBounds(context));
		return b2;
	}
	public function setContentFilters(filters:Array):Void{
		contentFilters = filters;
		base_mc.shell_mc.ph_mc.filters = contentFilters;
	}
	public function getContentMC():MovieClip{
		if(base_mc.shell_mc.ph_mc != null){
		return base_mc.shell_mc.ph_mc;
		}else{
		 return	base_mc.shell_mc;
		}
	}
	public function getFrameMC():MovieClip{
		return base_mc.shell_mc.frame_mc;
	}
	public function setX(x : Number) : Void{
		_x = x;
	}
	public function setY(y : Number) : Void{
		_y = y;
	}

	public function traceS():Void{
		trace(" base_mc " + base_mc._xscale + " " + base_mc._yscale + " " + base_mc._width + " " + base_mc._height);
		trace("   shell_mc " + base_mc.shell_mc._xscale + " " + base_mc.shell_mc._yscale + " " + base_mc.shell_mc._width + " " + base_mc.shell_mc._height);
		trace("     base_mc.shell_mc.ph_mc, " + base_mc.shell_mc.ph_mc._xscale + " " + base_mc.shell_mc.ph_mc._yscale + " " + base_mc.shell_mc.ph_mc._width + " " + base_mc.shell_mc.ph_mc._height);
	}
	public function setWidthHeight(w : Number, h : Number) : Void{
		this.width = w;
		this.height = h;
		trace("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
		traceS();
	//	trace("XXXXXXXXXXX Mixin SetContentWidth and Height" + w + " " + h + " curr " + this._width + " " + this._height + " " + util.Trace.me(this.base_mc));
		//scaleTo( base_mc,  base_mc.shell_mc.ph_mc);
		var xadj : Number = w/base_mc._owidth;
		var yadj : Number = h/base_mc._oheight;
	//	 trace("---------------- External/Stage Perspective----------");
		trace("xadj " + xadj + " = " + w  + "/ " +base_mc._owidth);
		trace("yadj " + yadj + " = " + h  + "/ " +base_mc._oheight); 
	//	 trace("---------------- Movie Perspective----------");
		var desiredWidth : Number = base_mc._oawidth *xadj ;
		var desiredHeight : Number = base_mc._oaheight*yadj;
		 
		trace("desiredWidth " + desiredWidth + " = " + xadj  + "/ " +base_mc._oawidth);
		trace("desiredHeight " + desiredHeight + " = " + yadj  + "/ " +base_mc._oaheight);
		//DEBUG base_mc.shell_mc.ph_mc._alpha = 30; 
		trace("ph actuals " + mcL.actTarget._oawidth + " "+mcL.actTarget._oaheight); 

		//-------------scale keeping the aspect ratio, then center the content-------------------
		//scaleTo(null, base_mc.shell_mc.ph_mc, desiredWidth,desiredHeight, mcL.actTarget.viewport_mc._width, mcL.actTarget.viewport_mc._height );
		if(mcL.actTarget.viewport_mc == null){
			trace("ERROR no view port ");
		//	snapshotDimensions(base_mc.shell_mc.ph_mc);
			trace(util.Trace.me(base_mc.shell_mc.ph_mc, "base_mc.shell_mc.ph_m"));
			scaleTo(null, base_mc.shell_mc.ph_mc,  desiredWidth,desiredHeight);
		}else{
			trace("HIGHLIGHTG using viewport");
//			snapshotDimensions(base_mc.shell_mc.ph_mc);
//			scaleTo(null, base_mc.shell_mc.ph_mc, base_mc._oawidth, base_mc._oaheight);
		//	snapshotDimensions(mcL.actTarget );
		var dw:Number = desiredWidth; /// mcL.actTarget.vp_owscale;
		var dh:Number = desiredHeight;// / mcL.actTarget.vp_ohscale;
	//	mcL.actTarget._width = dw;
	//	mcL.actTarget._height = dh;
			scaleTo(null, mcL.actTarget ,  dw,dh, mcL.actTarget.viewport_mc._width, mcL.actTarget.viewport_mc._height);
traceS();
		//	var b:Object = new Object();
		//	b._width = base_mc._owidth;
		//	b._height = base_mc._oheight;
		//	scaleTo2( base_mc.shell_mc.ph_mc, b);
		}	
		//------------ fill these to whatever the dimensions are -------------------------------------------
		base_mc.shell_mc.background_mc._width = desiredWidth;
		base_mc.shell_mc.background_mc._height = desiredHeight;
		base_mc.shell_mc.cover_mc._width = desiredWidth;
		base_mc.shell_mc.cover_mc._height = desiredHeight;
		base_mc.shell_mc.loadingProgress_mc._width = desiredWidth;
		base_mc.shell_mc.loadingProgress_mc._height = desiredHeight;
		base_mc.shell_mc.frame_mc._width = desiredWidth;
		base_mc.shell_mc.frame_mc._height =  desiredHeight;	
	}
	public function onSetContent() : Void{
		trace("#######################################################");
		trace("#######################onSetContent################################");
		trace("############### " + 	base_mc.shell_mc.ph_mc._width +", "+ 	base_mc.shell_mc.ph_mc._height +  " ################ orig " + base_mc._owidth + " " + base_mc._oheight  + " ########################");
		trace("#######################################################");
		var a : Alpha = new Alpha(base_mc.shell_mc.cover_mc);
		a.run(0,1500,Elastic.easeInOut,"onCallback");
		//scaleTo(null, base_mc.shell_mc.ph_mc, base_mc._owidth, base_mc._oheight); 
//		base_mc.shell_mc.ph_mc._width = width;//base_mc._owidth;
//		base_mc.shell_mc.ph_mc._height =height;// base_mc._oheight;
	}
	/*.................................................................*/
	function s0_viewAssetsLoaded(e : AEvent) : Function
	{
		this.onFunctionEnter ("s0_viewAssetsLoaded-", e, []);
		switch (e)
		{
			case ENTRY_EVT :
			{
				trace("AAAAAAAAAAAAAAAAAAAAAAAAAAA "+ _name +" 'MultiMediaWindow' s0_viewAssetsLoaded AAAAAAAAAAAAAAAAAAAAAAAAAAAA  \r " + util.Trace.me( owner));
			//	REQUIRE(owner != null, "MultiMediaWindow owner cannot be null");
				REQUIRE(base_mc != null, "MultiMediaWindow base_mc cannot be null");
				snapshotDimensions(base_mc);
				setWidthHeight(base_mc._width, base_mc._height);
		        ///create loading clips //////////
				createLoadingShell(base_mc);
				trace(util.Trace.me(this, "MultiMediaWindow check", false));

				hasOnLoad = true;
				///if these were set prior to onLoad/////////
				if(maskPATH != null){
					setMaskTo(maskPATH);
				}
				if(framePATH != null){
					setFrameTo(framePATH);
				}
				if(loadingProgressPATH != null){
					setLoadingProgressIndicatorTo(loadingProgressPATH);
				}
				if(contentPATH != null){
					setContentTo(contentPATH, null, contentFilters);
				}
				if(backgroundPATH != null){
					setBackgroundTo(backgroundPATH);
				}
				if(isDraggable){
					onPress = onPressHandler;
				}
				//owner.onChildClipLoad(this);
				return null;
			}
			case EXIT_EVT :
			{
				Q_TRAN(s0_viewAssetsUnLoaded);
				return null;
			}
			case INIT_EVT :
			{
				Q_TRAN(s1_creatingView);
				return null;
			}
		}
		return s_top;
	}

}